package cn.iocoder.yudao.module.ad.effect.service;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreLambdaQueryWrapper;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreQueryWrapper;
import cn.iocoder.yudao.framework.business.basic.service.impl.BaseService;
import cn.iocoder.yudao.module.ad.effect.convert.AdEffectRecordConvert;
import cn.iocoder.yudao.module.ad.effect.dal.dataobject.AdEffectRecordDO;
import cn.iocoder.yudao.module.ad.effect.dal.mysql.AdEffectRecordMapper;
import cn.iocoder.yudao.module.ad.effect.vo.AppAdEffectRecordQueryDTO;
import cn.iocoder.yudao.module.ad.effect.vo.AppAdEffectRecordVO;
import cn.iocoder.yudao.module.api.ad.effect.enums.AdEffectSceneEnum;
import cn.iocoder.yudao.module.api.ad.effect.enums.AdEffectTypeEnum;
import cn.iocoder.yudao.module.api.infrastructure.config.ConfigApiV2;
import cn.iocoder.yudao.module.api.infrastructure.config.dto.AdConfigRespDTO;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static cn.iocoder.yudao.module.api.infrastructure.ConfigConstants.CONFIG_AD;

/**
 * 广告效果记录 Service 实现类
 *
 * @author 山野羡民
 */
@Slf4j
@Service
@Validated
public class AppAdEffectRecordServiceImpl extends BaseService<AdEffectRecordDO, AppAdEffectRecordVO, AppAdEffectRecordQueryDTO> implements AppAdEffectRecordService {
    @Resource
    private AdEffectRecordMapper adEffectRecordMapper;

    @Resource
    @Lazy // 延迟，避免循环依赖报错
    private ConfigApiV2 configApiV2;

    @Override
    protected AdEffectRecordMapper getInjectedMapper() {
        return adEffectRecordMapper;
    }

    @Nonnull
    @Override
    protected CoreQueryWrapper<AdEffectRecordDO> buildQueryWrapper(AppAdEffectRecordQueryDTO param) {
        CoreQueryWrapper<AdEffectRecordDO> wrapper = super.buildQueryWrapper(param);
        wrapper.eqIfPresent("scene", param.getScene());
        wrapper.eqIfPresent("type", param.getType());
        wrapper.orderByDesc("update_time");
        return wrapper;
    }

    @Override
    public AppAdEffectRecordVO convertToViewObject(AdEffectRecordDO entity) {
        return AdEffectRecordConvert.INSTANCE.convert2(entity);
    }

    @Override
    public Long createIfNecessary(Long userId, AdEffectSceneEnum scene, AdEffectTypeEnum type, Long planId, Integer duration, Integer spendPrice) {
        CoreLambdaQueryWrapper<AdEffectRecordDO> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.eq(AdEffectRecordDO::getPlanId, planId);
        wrapper.eq(AdEffectRecordDO::getUserId, userId);
        wrapper.eq(AdEffectRecordDO::getType, AdEffectTypeEnum.TASK_SUBMIT.getValue());
        wrapper.between(AdEffectRecordDO::getCreateTime, LocalDateTimeUtil.beginOfDay(LocalDateTime.now()), LocalDateTimeUtil.endOfDay(LocalDateTime.now()));
        long count = getInjectedMapper().selectCount(wrapper);
        /*if (AdEffectTypeEnum.TASK_SUBMIT.equals(type) && count > 0) {
            log.warn("用户【{}】提交播放任务广告({})，但是今天已经提交过任务了，忽略重复提交", userId, planId);
            return null;
        }*/
        AdEffectRecordDO entity = new AdEffectRecordDO();
        entity.setUserId(userId);
        entity.setPlanId(planId);
        entity.setScene(scene.getValue());
        entity.setType(type.getValue());
        if (duration == null || duration <= 0) {
            duration = configApiV2.getConfig(CONFIG_AD, AdConfigRespDTO.class).getPlayMinSeconds();
        }
        entity.setDuration(duration);
        entity.setSpendPrice(spendPrice == null ? 0 : spendPrice);
        getInjectedMapper().insert(entity);
        return entity.getId();
    }

    @Override
    public Set<Long> getTodayCompletePlanIds(Long userId) {
        List<Long> planIds = getInjectedMapper().selectTodayCompletePlanIdsByUserId(userId);
        if (planIds == null) {
            planIds = List.of();
        }
        return new HashSet<>(planIds);
    }

}